﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
using System.Web.SessionState;

namespace UpdateApp
{
    /// <summary>
    /// UploaderFileByBaidu 的摘要说明
    /// 使用Session需要实现System.Web.SessionState.IRequiresSessionState接口
    /// </summary>
    public class UploaderFileByBaidu : IHttpHandler, System.Web.SessionState.IRequiresSessionState
    {
        string basePath = string.Empty;
        string dateDir = string.Empty;
        string upDir = string.Empty;

        string extName = string.Empty;
        string fileName = string.Empty;
        //完整路径文件名 压缩文件使用
        string fullName = string.Empty;

        string BaiduAppID = System.Configuration.ConfigurationManager.AppSettings["BaiduAppID"];
        string BaiduSecretKey = System.Configuration.ConfigurationManager.AppSettings["BaiduSecretKey"];
        public UploaderFileByBaidu()
        {
            basePath = FileHelper.GetUploadPath();
            dateDir = DateTime.Now.ToString("yyyy-MM-dd");
            upDir = basePath + "\\" + dateDir;
        }
        public void ProcessRequest(HttpContext context)
        {
            if (!Common.CheckUserHost())
            {
                var _result = "{\"jsonrpc\" : \"2.0\", \"result\" : \"没有上传权限\", \"id\" : \"" + fileName + "\"}";
                HttpContext.Current.Response.Write(_result);

                return;
            }

            context.Response.ContentEncoding = Encoding.UTF8;
            if (context.Request["REQUEST_METHOD"] == "OPTIONS")
            {
                context.Response.End();
            }

            try
            {
                bool isComplete = context.Request.Form["isComplete"] != null ? bool.Parse(context.Request.Form["isComplete"]) : false;

                //上传全部完成 将上传的文件包含无法下载的文件格式时直接将这些文件压缩
                if (isComplete)
                {
                    string list = ConfigurationManager.AppSettings["SuffixList"];

                    List<string> fileList = HttpContext.Current.Session["FileList"] != null ? (List<string>)HttpContext.Current.Session["FileList"] : new List<string>();

                    List<string> tempList = new List<string>();

                    foreach (var file in fileList.ToList())
                    {
                        foreach (var item in list.Split('|'))
                        {
                            if (Path.GetExtension(file).ToLower() == item.ToLower())
                            {
                                tempList.Add(file);
                                fileList.Remove(file);

                                break;
                            }
                        }
                    }

                    FileHelper.CreateZipFile(tempList);

                    return;
                }

                bool isMerge = context.Request.Form["isMerge"] != null ? bool.Parse(context.Request.Form["isMerge"]) : false;

                fileName = context.Request.Form["name"];

                bool flag = false;
                //分片上传
                if (context.Request.Form.AllKeys.Any(m => m == "chunk"))
                {
                    Common.SaveLog("开始分片上传：" + fileName);

                    ChunkUpload(context);
                }
                //合并文件
                else if (isMerge)
                {
                    Common.SaveLog("开始合并：" + fileName);

                    Merge(context);

                    flag = true;
                }
                else
                {
                    Common.SaveLog("开始上传：" + fileName);

                    SaveFile();

                    flag = true;
                }

                var _result = "{\"jsonrpc\" : \"2.0\", \"result\" : null, \"id\" : \"" + fileName + "\"}";
                HttpContext.Current.Response.Write(_result);
            }
            catch (Exception ex)
            {
                Common.SaveLog(ex.ToString());
            }
        }

        public void ChunkUpload(HttpContext context)
        {
            int chunk = Convert.ToInt32(context.Request.Form["chunk"]);     // 当前分片
            int chunks = Convert.ToInt32(context.Request.Form["chunks"]);   // 分片总计

            var md5 = context.Request.Form["md5"];

            //临时保存分块的目录 可以多人同时上传同一文件
            var dir = Path.Combine(upDir, md5);
            if (!Directory.Exists(dir))
                Directory.CreateDirectory(dir);

            var filePath = Path.Combine(dir, chunk.ToString());

            //表单中取得分块文件
            var data = HttpContext.Current.Request.Files["file"];

            //为null可能是暂停的那一瞬间
            if (data != null)
            {
                data.SaveAs(filePath);
            }
        }
        //合并文件
        public void Merge(HttpContext context)
        {
            string md5 = context.Request.Form["md5"];

            var dir = Path.Combine(upDir, md5);

            var files = Directory.GetFiles(dir);
            fullName = Path.Combine(upDir, fileName);

            var fs = new FileStream(fullName, FileMode.Create);

            //排序，保证从0-N Write
            foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))
            {
                var bytes = File.ReadAllBytes(part);
                fs.Write(bytes, 0, bytes.Length);
                bytes = null;
                File.Delete(part);
            }

            fs.Close();

            Directory.Delete(dir);

            //压缩备用
            List<string> fileList = HttpContext.Current.Session["FileList"] != null ? (List<string>)HttpContext.Current.Session["FileList"] : new List<string>();

            fileList.Add(fullName);

            HttpContext.Current.Session["FileList"] = fileList;
        }

        /// <summary>
        /// 文件保存操作
        /// </summary>
        /// <param name="basePath"></param>
        public void SaveFile()
        {
            HttpFileCollection files = HttpContext.Current.Request.Files;

            if (files.Count == 0 && !string.IsNullOrWhiteSpace(fileName))
            {
                var result = "{\"jsonrpc\" : \"2.0\", \"error\" :  \"保存失败\",\"id\" :  \"id\"}";
                HttpContext.Current.Response.Write(result);
            }

            if (!Directory.Exists(upDir))
                Directory.CreateDirectory(upDir);

            if (!string.IsNullOrEmpty(fileName))
            {
                fullName = Path.Combine(upDir, fileName);

                //fullName = fullName.EndsWith(".log", true, null) || fullName.EndsWith(".ini", true, null) ? fullName + ".txt" : fullName;

                files[0].SaveAs(fullName);

                Common.SaveLog("保存：" + fileName);

                //压缩备用
                List<string> fileList = HttpContext.Current.Session["FileList"] != null ? (List<string>)HttpContext.Current.Session["FileList"] : new List<string>();

                fileList.Add(fullName);

                HttpContext.Current.Session["FileList"] = fileList;

                if (fullName.EndsWith("data.json", true, null))
                {
                    //开始翻译
                    Thread thread = new Thread(Translate);
                    thread.Start();
                }
            }
            else
            {
                files.AllKeys.ToList().ForEach(f =>
                {
                    if (!string.IsNullOrWhiteSpace(files[f].FileName))
                    {
                        //winCE上传的文件，FileName会包含该文件在winCE的目录，保存会失败，所以要只取文件名
                        //很坑
                        fileName = Path.GetFileName(files[f].FileName);
                        fullName = Path.Combine(upDir, fileName);

                        //fullName = fullName.EndsWith(".log", true, null) || fullName.EndsWith(".ini", true, null) ? fullName + ".txt" : fullName;

                        Common.SaveLog("保存：" + fileName);

                        files[f].SaveAs(fullName);

                        //压缩不能下载的文件
                        string list = ConfigurationManager.AppSettings["SuffixList"];

                        List<string> tempList = new List<string>();

                        foreach (var item in list.Split('|'))
                        {
                            if (Path.GetExtension(fullName).ToLower() == item.ToLower())
                            {
                                tempList.Add(fullName);

                                break;
                            }
                        }

                        FileHelper.CreateZipFile(tempList);
                    }
                });
            }
        }

        private void Translate()
        {
            List<string> list = FileHelper.ReadFileList(fullName);
            List<string> temps = new List<string>();

            foreach (var item in list)
            {
                List<string> arr = item.Split('=').ToList();

                string temp = arr[0];

                TransApi transApi = new TransApi(BaiduAppID, BaiduSecretKey);
                string result = transApi.GetTransResult(temp, "auto", "auto").Trim();

                //当为中文时去除包含的英文
                if (Regex.IsMatch(temp.Substring(0, 1), "^[\u4e00-\u9fa5]{0,}$"))
                {
                    temp = Regex.Replace(temp, "[a-z]", "", RegexOptions.IgnoreCase);

                    arr[0] = result;
                    arr.Add(temp);
                }
                //当为英文时，将英文置前，中文置后
                else
                {
                    arr[0] = temp;
                    arr.Add((result));
                }

                string row = string.Join("=", arr);

                temps.Add(row);

                //翻译请求1秒一次
                Thread.Sleep(1200);
            }

            FileHelper.WriteListToTextFile(temps, fullName);
        }


        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
